// 
//  MainWindow.cs
//  
//  Author:
//       Nikita Tsukanov <keks9n@gmail.com>
// 
//  Copyright (c) 2011 Nikita Tsukanov
// 
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU General Public License for more details.
//  
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// 



using System;
namespace SkypeTab
{
	public partial class MainWindow : Gtk.Window
	{
		
		
		bool IsHidden=true;

		ManagedWindow MyWindow;
		private Gdk.Pixbuf NormalIcon, UrgentIcon;
		bool IsBlinking;
		
		[System.Runtime.InteropServices.DllImport("libgtk-x11-2.0.so.0")]
		public static extern void gtk_notebook_set_action_widget(IntPtr notebook, IntPtr widget, Gtk.PackType ptype);
		
		private void PrepareIcon ()
		{
			var SkypeIcon=System.Drawing.Bitmap.FromFile("/usr/share/pixmaps/skype.png");
			System.IO.Stream stream=
				System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("SkypeTab.img.icon_mod.png");
			var IconMod=System.Drawing.Bitmap.FromStream(stream);
			var tmp= System.Drawing.Graphics.FromImage((System.Drawing.Image)SkypeIcon);
			int size=SkypeIcon.Width/2;
			tmp.DrawImage(IconMod, size,size,size,size);
			stream= new System.IO.MemoryStream();
			SkypeIcon.Save( stream,System.Drawing.Imaging.ImageFormat.Png);
			stream.Seek(0,System.IO.SeekOrigin.Begin);
			UrgentIcon=new Gdk.Pixbuf(stream);
		}
		
		public MainWindow () : base(Gtk.WindowType.Toplevel)
		{
			
			this.Build ();
			Notebook.Scrollable=true;
			Notebook.EnablePopup=true;
			
			var abtn=new Gtk.Button();
			abtn.Image=new Gtk.Image("gtk-dialog-info",Gtk.IconSize.Button);
			gtk_notebook_set_action_widget(Notebook.Handle, abtn.Handle,Gtk.PackType.End);
			abtn.CanFocus=false;
			abtn.Clicked+= delegate {
				AboutDialog.ShowAbout();
			};
			abtn.Show();
			
			Realize();
			MyWindow=new ManagedWindow(GdkWindow);
			Notebook.CanFocus=false;
			Notebook.SwitchPage+= delegate {
				var wr=(XWinWrapper)Notebook.CurrentPageWidget;
				wr.Sync();
				wr.SetFocus();
				
				
			};
			FocusInEvent+= delegate {
				var wr=(XWinWrapper)Notebook.CurrentPageWidget;
				if(wr!=null)
					wr.SetFocus();
				IsHidden=false;
			};
			NormalIcon = new Gdk.Pixbuf ("/usr/share/pixmaps/skype.png");
			PrepareIcon();
			this.Icon=NormalIcon;
			
			new Timer(RescanWindows, 500);
			new Timer(BlinkIcon, 500);

		}
		
		private void BlinkIcon(object o, EventArgs ea)
		{
			if(!IsBlinking)
				Icon=NormalIcon;
			else
			{
				Icon=(Icon==NormalIcon)?UrgentIcon:NormalIcon;
			}
		}
		
		protected override void OnStateChanged (Gtk.StateType previous_state)
		{
			base.OnStateChanged (previous_state);
		}
        
		
		protected override bool OnExposeEvent (Gdk.EventExpose evnt)
		{
			IsHidden=false;
			return base.OnExposeEvent (evnt);
		}
		
		
		
		private void RescanWindows (object o, EventArgs ea)
		{
			
			
			XWinWrapper wrap = null;
			
			var alive = X11.X.GetAllChildren (MyWindow.Handle);
			int i = 0;
			
			while (i < Notebook.NPages)
			{
				bool iconic = !MyWindow.Visible;
				wrap = (XWinWrapper)Notebook.GetNthPage (i);
				if ((!alive.Contains (wrap.Window.Handle)) ||
				   ((!iconic) && (!wrap.Window.Visible)))
				{
					wrap.Reset ();
					Notebook.RemovePage (i);
				}
			
				else
					i++;
			}
			
		
			
			//Look around for new windows
			foreach (var h in X11.X.GetTopLevels ())
			{
				
				var classname = X11.X.GetWindowClass (h);
				if ((classname == null) || (classname.ToLower () != "skype"))
					continue;
				Console.WriteLine ("Found skype window: 0x" + h.ToString ("x"));
				
				this.Realize ();
				this.ShowNow ();
				Notebook.ShowNow ();
				this.Present ();

				
				var mw = new ManagedWindow (h);
				wrap = new XWinWrapper ();
				var hdr = new TabHeader (mw.Name);
				hdr.Tag = wrap;
				hdr.CloseRequest += HandleHdrCloseRequest;
				int page_number = 0;
				if (System.Text.RegularExpressions.Regex.Match (hdr.Text, "Skype.*(Beta)").Value.Length > 0)
				{
					hdr.HasCloseButton = false;
					Notebook.InsertPageMenu (wrap, hdr, hdr.MenuLabel, 0);
				}
				else
					page_number = Notebook.AppendPageMenu (wrap, hdr, hdr.MenuLabel);
				Notebook.CurrentPage = page_number;
				Notebook.ShowNow ();
				wrap.ShowNow ();
				ShowAll ();
				
				
				
				wrap.Realize ();
				wrap.WrapWindow (mw);
				
				Gtk.Application.Invoke (delegate
				{
					Notebook.CurrentPage = page_number;

					IsHidden = false;
				});
			
			}
			if (X11.X.GetTopWindow() == MyWindow.Handle)
			{
				var xwr = (XWinWrapper)Notebook.CurrentPageWidget;
				if (xwr != null)
					xwr.SetFocus ();	
			}

			bool found_urgent=false;
				
			//Sync pages
			for(int c=0; c<Notebook.NPages; c++)
			{
				
				wrap=(XWinWrapper)Notebook.GetNthPage(c);
				var hdr=(TabHeader)Notebook.GetTabLabel(wrap);
				hdr.Text=wrap.Window.Name;
				wrap.Sync();
				hdr.Notify=hdr.Text.StartsWith("*");
				if(hdr.Notify)
					found_urgent=true;
					
			}
			IsBlinking=found_urgent;
			UrgencyHint=found_urgent;
			
			//Raise active tab
			wrap=(XWinWrapper)Notebook.CurrentPageWidget;
			if (wrap!=null)
			{
				wrap.Window.Raise();
				Title=wrap.Window.Name;
			}
			
			if(Notebook.NPages==0)
			{
				IsHidden=true;
				Hide();
			}
			
			
				
			
		}

		void HandleHdrCloseRequest (object sender, EventArgs e)
		{
			var wrap=(XWinWrapper)((TabHeader)sender).Tag;
			wrap.Window.Destroy();
			wrap.Reset();
			Notebook.RemovePage(Notebook.PageNum(wrap));
		}
    
		protected override bool OnDeleteEvent (Gdk.Event evnt)
		{
			if(!IsHidden)
			{
				while(Notebook.NPages!=0)
				{
					var wr=(XWinWrapper)Notebook.GetNthPage(0);
					wr.Window.Destroy();
					wr.Reset();
					Notebook.RemovePage(0);
				}
				IsHidden=true;
				Hide();
				return true;
			}
			Gtk.Application.Quit();
			return base.OnDeleteEvent (evnt);
		}
		
			                  
	}
}

